﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;

namespace Extented.UI.Core.Native
{
    public class RenderTextBlockContext : FrameworkRenderElementContext
    {
        protected override int RenderChildrenCount
        {
            get { return Child != null ? 1 : 0; }
        }
        protected override FrameworkRenderElementContext GetRenderChild(int index)
        {
            return Child;
        }
        string text;
        string highlightedText;
        HighlightedTextCriteria criteria;
        TextTrimming? textTrimming;
        TextWrapping? textWrapping;
        TextAlignment? textAlignment;
        TextDecorationCollection textDecorations;
        bool forceUseRealTextBlock;
        public bool IsRealTextBlockInitialized { get { return Child != null; } }
        public string Text
        {
            get { return text; }
            set
            {
                SetProperty(ref text, value, FREInvalidateOptions.UpdateLayout, () => Child.Do(x => x.Text = value));
            }
        }
        public bool ForceUseRealTextBlock
        {
            get { return forceUseRealTextBlock; }
            set { SetProperty(ref forceUseRealTextBlock, value); }
        }
        public HighlightedTextCriteria HighlightedTextCriteria
        {
            get { return criteria; }
            set { SetProperty(ref criteria, value, FREInvalidateOptions.UpdateLayout, () => Child.Do(x => x.HighlightedTextCriteria = value)); }
        }
        public string HighlightedText
        {
            get { return highlightedText; }
            set
            {
                SetProperty(ref highlightedText, value, FREInvalidateOptions.None);
                if (ShouldAdditionalUpdateOnHighlightedTextChanged(value, textDecorations != null))
                    UpdateLayout(FREInvalidateOptions.UpdateSubTree);
                Child.Do(x => x.HighlightedText = value);
            }
        }
        bool ShouldAdditionalUpdateOnHighlightedTextChanged(string ht, bool hasDecorations)
        {
            if (hasDecorations)
                return true;
            if (string.IsNullOrEmpty(ht) && IsRealTextBlockInitialized)
                return true;
            if (!string.IsNullOrEmpty(ht) && !IsRealTextBlockInitialized)
                return true;
            return false;
        }
        public TextTrimming? TextTrimming
        {
            get { return textTrimming; }
            set { SetProperty(ref textTrimming, value, FREInvalidateOptions.UpdateSubTree); }
        }
        public TextWrapping? TextWrapping
        {
            get { return textWrapping; }
            set { SetProperty(ref textWrapping, value, FREInvalidateOptions.UpdateSubTree); }
        }
        public TextAlignment? TextAlignment
        {
            get { return textAlignment; }
            set { SetProperty(ref textAlignment, value); }
        }
        public TextDecorationCollection TextDecorations
        {
            get { return textDecorations; }
            set { SetProperty(ref textDecorations, value, FREInvalidateOptions.AffectsRenderCaches, () => Child.Do(x => x.TextDecorations = value)); }
        }
        public TextDecorationCollection CachedTextDecorations { get; internal set; }
        public FormattedText FormattedText { get; internal set; }
        public Typeface Typeface { get; internal set; }
        public RenderRealTextBlockContext Child { get; private set; }
        public bool UseRealTextBlock { get { return Child != null; } }
        public RenderTextBlockContext(RenderTextBlock factory)
            : base(factory)
        {
        }
        protected override void ResetTemplatesAndVisualsInternal()
        {
            base.ResetTemplatesAndVisualsInternal();
            if (Child != null)
            {
                RemoveChild(Child);
                Child = null;
            }
        }
        protected override void OnForegroundChanged(object oldValue, object newValue)
        {
            base.OnForegroundChanged(oldValue, newValue);
            UpdateLayout(FREInvalidateOptions.UpdateLayout);
        }
        protected override void OnFlowDirectionChanged(FlowDirection? oldValue, FlowDirection? newValue)
        {
            UpdateLayout(FREInvalidateOptions.UpdateLayout);
        }
        public override bool ShouldUseMirrorTransform()
        {
            var bValue = base.ShouldUseMirrorTransform();
            if (FlowDirection == System.Windows.FlowDirection.RightToLeft)
                return !bValue;
            return bValue;
        }
        protected override void ResetRenderCachesInternal()
        {
            base.ResetRenderCachesInternal();
            FormattedText = null;
            Typeface = null;
            CachedTextDecorations = null;
        }
        public override void AddChild(FrameworkRenderElementContext child)
        {
            base.AddChild(child);
            Child = (RenderRealTextBlockContext)child;
        }
        public override void RemoveChild(FrameworkRenderElementContext child)
        {
            base.RemoveChild(child);
            Child = null;
        }
    }
}
